package cn.edu.nju.ws.sview.rdf;

import java.io.IOException;
import java.util.Properties;

import cn.edu.nju.ws.sview.cache.BlankNodeLabelCache;
import cn.edu.nju.ws.sview.cache.URIIDCache;
import cn.edu.nju.ws.sview.cache.URILabelCache;


/**
 *RDF resource factory
 * 
 * @author Gong Saisai
 * 
 */
public class ResourceFactory {
	final public  static String INTERNAL_URI_PREFIX;
	final public static String CUSTOM_DATAMEMBER_URI_PREFIX;
	final public static String CUSTOM_FACET_URI_PREFIX;
	static{
		Properties properties = new Properties();
		try {
			properties.load(ResourceFactory.class.getClassLoader().getResourceAsStream("conf.properties")) ;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		INTERNAL_URI_PREFIX = properties.getProperty("internal_uri_prefix");
		CUSTOM_DATAMEMBER_URI_PREFIX = INTERNAL_URI_PREFIX+"dm/";
		CUSTOM_FACET_URI_PREFIX = INTERNAL_URI_PREFIX+"facet/";
		properties.clear();
	}
	
	private static ResourceFactory INSTANCE = null;
	
	private ResourceFactory() {
	}

	public static synchronized ResourceFactory getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new ResourceFactory();
		}
		return INSTANCE;
	}

	/**
	 * create URI resource
	 * @param uriStr the URIResource's uri string
	 * @return the new URIResource created
	 */
	public URIResource createURIResource(String uriStr) {
		if (uriStr == null) {
			throw new IllegalArgumentException("The uri string of the URIResource to be created must not be null.");
		}
	    URIResource uri =new URIResource(uriStr);
	    return uri;
	}

	/**
	 * create blank node
	 * 
	 * @param blankNodeId
	 *            blank node id in the rdf document
	 * @param rdfDocument
	 *            the rdf document the blank node belongs to
	 * @return the new Blank node created
	 */
	public BlankNode createBlankNode(
			int blankNodeId,
			RDFDocument rdfDocument) {
		if (rdfDocument==null) {
			throw new IllegalArgumentException("The rdf document to which blank node belongs must not be null.");
		}
		BlankNode blankNode = new BlankNode(rdfDocument,blankNodeId);
		return blankNode;
	}

	/**
	 * 创建plain literal
	 * 
	 * @param lexicalForm
	 *            待创建的plain literal的lexical form
	 * @param languageTag
	 *            待创建的plain literal的language tag ，如果不指定应该使用"";
	 * @return 新创建的plain literal
	 */
	public PlainLiteral createPlainLiteral(String lexicalForm,
			String languageTag) {
		if (lexicalForm == null) {
			throw new IllegalArgumentException("创建的literal的lexical form不能为null");
		}
		if(languageTag==null){
			throw new IllegalArgumentException("创建的literal的language tag不能为null");
		}
		PlainLiteral plainLiteral = new PlainLiteral(lexicalForm, languageTag);
		return plainLiteral;
	}

	/**
	 * 创建typed literal
	 * 
	 * @param lexicalForm
	 *            待创建的typed literal的lexical form
	 * @param datatypeURIStr
	 *            待创建的typed literal的datatype的URI的字符串形式
	 * @return 新创建的typed literal
	 */
	public TypedLiteral createTypedLiteral(String lexicalForm,
			String datatypeURIStr) {
		if (lexicalForm == null) {
			throw new IllegalArgumentException("创建的literal的lexical form不能为null");
		}
		if (datatypeURIStr == null) {
			throw new IllegalArgumentException(
					"创建的typed literal的datatype的URI不能为null");
		}
		URIResource datatypeURI = this.createURIResource(datatypeURIStr);
		TypedLiteral typedLiteral = new TypedLiteral(lexicalForm,datatypeURI);
		return typedLiteral;
	}
	
	/**
	 * 创建RDFDocument
	 * @param uri document URI
	 * @return
	 */
	public RDFDocument createRDFDocument(String uri){
		return new RDFDocument(uri) ;
	}
	
	/**
	 * 创建TemporaryRDFResource为Magicsets中创建magic predicate服务
	 * @param resource
	 * @return
	 */
	public Resource createTemporaryRDFResource(Resource resource){
		TemporaryRDFResource magicResource = new TemporaryRDFResource(resource) ;
		return magicResource;
	}
	
	/**
	 * 创建SupmagicResource为Magicsets中创建supplementary  predicate服务
	 * @param resource
	 * @return
	 */
	public Resource createSupmagicResource(int ruleId, int literalPos) {
		// TODO Auto-generated method stub
		SupmagicResource supMagicRes = new SupmagicResource(ruleId,literalPos) ;
		return supMagicRes;
	}
	
	/**
	 * 取得resource label
	 * @param resource. URIResource or BlankNode
	 * @param lang. the language
	 * @return the optimal label. Empty if none
	 */
	public String getResouceLabel(Resource resource,String lang){
		String label = "";
		try {
			if (resource instanceof URIResource) {
				URIResource uriResource = (URIResource) resource;
				String uri = uriResource.getURI();
				int uriID = URIIDCache.getInstance().getURIID(uri, true);
				label = URILabelCache.getInstance().getLabel(uriID, lang);
			} else if (resource instanceof BlankNode) {
				BlankNode blankNode = (BlankNode) resource;
				int documentID = URIIDCache.getInstance().getURIID(
						blankNode.getRDFDocument().getURI().getURI(), true);
				int blankNodeID = blankNode.getBlankNodeID();
				label = BlankNodeLabelCache.getInstance().getLabel(documentID,
						blankNodeID, lang);
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return label;
	}
	
	/**
	 * create custom datamember uri resource for reasoning 
	 * which must be the form INTERNAL_URI_PREFIX+ "dm/group/isInner/classID/isCopy/name"
	 * @param group
	 * @param name
	 * @return
	 */
	public URIResource createCustomDatamemberURIResource(String group,String name,boolean isInner,int classID,boolean isCopy){
		String uri = ResourceFactory.INTERNAL_URI_PREFIX+"dm/"+group+"/"+isInner+"/"+classID+"/"+isCopy+"/"+name;
		URIResource uriResource = createURIResource(uri);
		return uriResource;
	}
}